package annotation;


import annotation.define.ExtractInterface;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;


/**
 * 使用APT处理注释
 *
 * @author sun.ye
 * @since 2020-05-11 21:16
 */
public class InterfaceExtractorProcessor implements AnnotationProcessor {

    private final AnnotationProcessorEnvironment environment;

    private ArrayList<MethodDeclaration> interfanceMethods = new ArrayList<>();

    public InterfaceExtractorProcessor(AnnotationProcessorEnvironment environment) {
        this.environment = environment;
    }


    @Override
    public void process() {

        for (TypeDeclaration typeDeclaration : environment.getTypeDeclarations()) {
            ExtractInterface annotation = typeDeclaration.getAnnotation(ExtractInterface.class);
            if (annotation == null) {
                break;
            }

            for (MethodDeclaration methodDeclaration : typeDeclaration.getMethods()) {
                if(methodDeclaration.getModifiers().contains(Modifier.PUBLIC) && !(methodDeclaration.getModifiers().contains(Modifier.STATIC))){
                    interfanceMethods.add(methodDeclaration);
                }
            }
            if (!interfanceMethods.isEmpty()){
                try{
                    PrintWriter writer = environment.getFiler().createSourceFile(annotation.value());
                    writer.println("package " + typeDeclaration.getPackage().getQualifiedName() + ";");
                    writer.println("public interface " + annotation.value() + "{" );
                    for (MethodDeclaration methodDeclaration : interfanceMethods) {
                        writer.print("  public ");
                        writer.print(methodDeclaration.getReturnType() + " ");
                        writer.print(methodDeclaration.getSimpleName() + " (");
                        int i = 0;
                        for (ParameterDeclaration param : methodDeclaration.getParameters() ) {
                            writer.write(param.getType() + " " +param.getSimpleName());
                            if (++i < methodDeclaration.getParameters().size()){
                                writer.print(", ");
                            }
                        }
                        writer.println(");");
                        writer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}